library riki_login;

import 'dart:async';
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:riki_login/config/global.dart';
import 'package:riki_login/entity/login_arg.dart';
import 'package:riki_login/entity/user_login_entity.dart';
import 'package:riki_login/pages/user/user_login_management/user_login_manager.dart';
import 'package:riki_login/router/riki_login_router.dart';
import 'package:riki_login/utils/device_info_util.dart';

import 'api/base_api.dart';
import 'api/designer/designer_api.dart';
import 'package:gm_login_plugin/models/gm_login_model.dart';

import 'api/oauth/oauth_api.dart';
import 'entity/staff_login_entity.dart';

/// 点击隐私协议
typedef OnPrivacyPolicyClick = void Function(BuildContext context);

/// 点击平台协议
typedef OnPlatformAgreementClick = void Function(BuildContext context);

/// 登录成功回调
typedef OnLoginSuccessCallback = void Function(BuildContext context);

/// 登录过期回调
typedef OnLoginDateCallback = void Function(BuildContext context);

enum AppType {
  /// 用户 App
  user,

  /// 服务App
  staff,
}

class RikiLogin {
  factory RikiLogin() => _getInstance();

  static RikiLogin get instance => _getInstance();
  static RikiLogin? _instance;

  LoginManager loginManager = LoginManager();

  RikiLogin._internal();

  static RikiLogin _getInstance() {
    if (_instance == null) {
      _instance = RikiLogin._internal();
    }
    return _instance!;
  }

  bool _isInit = false;
  bool _isInitRouter = false;

  static const String PACKAGE = 'riki_login';

  static const String storageLoginUserInfoKey = 'loginUserInfo';

  static const String storageLoginStaffInfoKey = 'loginStaffInfo';

  static const String storageUserAgreeAgreementKey = 'is_user_agree_agreement';
  static const String storageStaffAgreeAgreementKey = 'is_staff_agree_agreement';

  late BuildContext _context;

  set context(BuildContext context) => this._context = context;

  BuildContext get context => _context;

  /// 接口地址
  late String _apiUrl;
  String get apiUrl => _apiUrl;

  /// 主颜色
  Color? _primaryColor;
  Color? get primaryColor => _primaryColor;

  /// APP版本号
  late String _version;
  String get version => _version;

  /// 证书名称
  late String _cerName;
  String get cerName => _cerName;

  /// 微信ID
  late String _wechatAppId;
  String get wechatAppId => _wechatAppId;

  /// 微信link
  late String _wechatUniversalLink;
  String get wechatUniversalLink => _wechatUniversalLink;

  /// 国美AppId
  late String _gmAppId;
  String get gmAppId => _gmAppId;

  /// web地址域名
  late String _h5Url;
  String get h5Url => _h5Url;

  // /// 存储用户信息key
  // late String _storageLoginUserInfoKey;
  // String get storageLoginUserInfoKey => _storageLoginUserInfoKey;
  //
  // /// 存储勾选协议信息key
  // late String _storageAgreeAgreementKey;
  // String get storageAgreeAgreementKey => _storageAgreeAgreementKey;

  /// 网易易盾AppKey
  late String _netEasyAppKey;
  String get netEasyAppKey => _netEasyAppKey;

  /// APP类型 （User、 staff）
  late AppType _appType;
  AppType get appType => _appType;

  /// 国美 gmWechatScope
  late String _gmWechatScope;
  String get gmWechatScope => _gmWechatScope;

  /// 国美 gmWechatState
  late String _gmWechatState;
  String get gmWechatState => _gmWechatState;

  /// 开发环境
  late bool _isDebug;
  bool get isDebug => _isDebug;

  /// 是否是开发者
  late bool _developLogin;
  bool get developLogin => _developLogin;

  /// 国美登录logo
  late String _userLoginIcLoginLogo;
  String get userLoginIcLoginLogo => _userLoginIcLoginLogo;

  /// 国美登录按钮（普通）
  late String _userLoginIcLoginBlueBgNormal;
  String get userLoginIcLoginBlueBgNormal => _userLoginIcLoginBlueBgNormal;

  /// 国美登录按钮（按下）
  late String _userLoginIcLoginBlueBgDisable;
  String get userLoginIcLoginBlueBgDisable => _userLoginIcLoginBlueBgDisable;

  /// 国美勾选协议选中状态
  late String _userLoginIcLoginAgreeSelectedIcon;
  String get userLoginIcLoginAgreeSelectedIcon => _userLoginIcLoginAgreeSelectedIcon;

  /// 国美勾选协议未选中状态
  late String _userLoginIcLoginAgreeUnselectedIcon;
  String get userLoginIcLoginAgreeUnselectedIcon => _userLoginIcLoginAgreeUnselectedIcon;

  /// 协议是否勾选
  late bool _isAgreement;
  bool get isAgreement => _isAgreement;

  /// 点击平台协议
  late OnPlatformAgreementClick _onPlatformAgreementClick;
  OnPlatformAgreementClick get onPlatformAgreementClick => _onPlatformAgreementClick;

  /// 点击隐私政策
  late OnPrivacyPolicyClick _onPrivacyPolicyClick;
  OnPrivacyPolicyClick get onPrivacyPolicyClick => _onPrivacyPolicyClick;

  /// 登录返回路径
  late String _path;
  String get path => _path;

  /// 登录成功回调
  late OnLoginSuccessCallback _onLoginSuccessCallback;
  OnLoginSuccessCallback get onLoginSuccessCallback => _onLoginSuccessCallback;

  /// 登录过期回调
  late OnLoginDateCallback _onLoginDateCallback;
  OnLoginDateCallback get onLoginDateCallback => _onLoginDateCallback;

  /// user 用户实体
  late UserLoginEntity _userLoginEntity;
  UserLoginEntity get userLoginEntity => _userLoginEntity;

  /// staff 用户实体
  late StaffLoginEntity _staffLoginEntity;
  StaffLoginEntity get staffLoginEntity => _staffLoginEntity;

  /// user初始化
  /// [context] 上下文对象
  /// [apiUrl] 接口路径
  /// [h5Url] 协议路径
  /// [version] 国美登陆App版本号
  /// [primaryColor] 主色调
  /// [cerName] 国美登陆证书名称
  /// [wechatAppId] 国美登录安卓使用 微信AppId
  /// [gmAppId] 国美登录AppId
  /// [userLoginIcLoginAgreeUnselectedIcon]  国美登录页协议未选中图片
  /// [developLogin] UserAPP当前是否是开发者使用
  /// [isDebug] 当前开发环境（配置国美登录环境使用安卓SDK）
  /// [storageAgreeAgreementKey] 开发者使用时，是否勾选协议存储key

  /// [OnLoginDateCallback] 登录过期回调

  void initUser({
    required BuildContext context,
    required String apiUrl,
    required String h5Url,
    required String version,
    required Color primaryColor,
    required String cerName,
    required String wechatAppId,
    required String gmAppId,
    required bool developLogin,
    required bool isDebug,
    required String wechatUniversalLink,
    required OnPlatformAgreementClick onPlatformAgreementClick,
    required OnPrivacyPolicyClick onPrivacyPolicyClick,
    required OnLoginSuccessCallback onLoginSuccessCallback,
    required OnLoginDateCallback onLoginDateCallback,
  }) {
    if (_isInit) return;
    this._context = context;
    this._apiUrl = apiUrl;
    this._h5Url = h5Url;
    this._version = version;
    this._primaryColor = primaryColor;
    this._cerName = cerName;
    this._wechatAppId = wechatAppId;
    this._gmAppId = gmAppId;
    this._developLogin = developLogin;
    this._isDebug = isDebug;
    this._onPrivacyPolicyClick = onPrivacyPolicyClick;
    this._onPlatformAgreementClick = onPlatformAgreementClick;
    this._path = path;
    this._onLoginSuccessCallback = onLoginSuccessCallback;
    this._onLoginDateCallback = onLoginDateCallback;
    this._wechatUniversalLink = wechatUniversalLink;
    this._appType = AppType.user;

    /// 国美登录初始化
    loginManager.initEnviriment();

    this._userLoginEntity = RikiLoginGlobal.getLocalUserAccount() ?? UserLoginEntity();
    this._isAgreement = RikiLoginGlobal.isUserAgreeAgreement();

    if (!_isInitRouter) {
      _isInitRouter = true;
      RikiLoginRouter.register();
    }
    this._isInit = true;
  }

  /// staff初始化
  /// [context] 上下文对象
  /// [apiUrl] 接口路径
  /// [h5Url] 协议路径
  /// [primaryColor] 主色调
  /// [storageAgreeAgreementKey] 开发者使用时，是否勾选协议存储key
  /// [storageLoginUserInfoKey] user 登录信息本地存储key
  /// [onPlatformAgreementClick] 点击平台政策协议
  /// [onPrivacyPolicyClick] 点击隐私政策协议

  void initStaff({
    required BuildContext context,
    required String apiUrl,
    required String h5Url,
    required Color primaryColor,
    required OnPlatformAgreementClick onPlatformAgreementClick,
    required OnPrivacyPolicyClick onPrivacyPolicyClick,
    required OnLoginSuccessCallback onLoginSuccessCallback,
  }) {
    if (_isInit) return;
    this._context = context;
    this._apiUrl = apiUrl;
    this._h5Url = h5Url;
    this._primaryColor = primaryColor;

    this._onPrivacyPolicyClick = onPrivacyPolicyClick;
    this._onPlatformAgreementClick = onPlatformAgreementClick;
    this._onLoginSuccessCallback = onLoginSuccessCallback;

    this._appType = AppType.staff;

    _initSpData();

    if (!_isInitRouter) {
      _isInitRouter = true;
      RikiLoginRouter.register();
    }
    this._isInit = true;
  }


  /// 获取本地数据
  void _initSpData ()async{
   await SpUtil.getInstance();
    var loginEntity = RikiLoginGlobal.getLocalStaffAccount() ?? StaffLoginEntity();

    refreshStaffLoginEntity(loginEntity,init: true);

    bool isAgree = RikiLoginGlobal.isStaffAgreeAgreement();

    refreshAgreeAgreement(isAgree);
  }




  /// 唤起登陆页面
  Future<bool> login(BuildContext context) async {
    if (appType == AppType.user) {
      if (developLogin) {
        print('2222222222222222');
        NavigatorUtils.push(context, RikiLoginRouter.userLoginCode, params: LoginArg(path: ''));
        return false;
      } else {
        print('''''''object''''''');
        return await loginManager.login(context);
      }
    } else if (appType == AppType.staff) {
      NavigatorUtils.push(context, RikiLoginRouter.staffLoginCode,transition: TransitionType.fadeIn,clearStack: true);
      return true;
    }
    return false;
  }

  /// user 登陆接口 在login成功之后 staff 和 user开发者 跳转登录页面走登陆回调
  Future<bool> userLogin() async {
    GMMLoginInfo info = await loginManager.getLoginInfo();
    return await oauthGomeLogin(info.scn!);
  }

  /// 退出登录, 返回退出登录状态
  Future<bool> logOut() async {
    // 清除数据
    if (appType == AppType.user) {
      if (RikiLogin.instance.developLogin) {
        // 如果是开发者
        return true;
      }
      return await loginManager.logOut();
    } else {
      return true;
    }
  }

  ///  获取登录状态
  bool getLoginStatus() {
    if (appType == AppType.user) {
      return RikiLoginGlobal.isLoginUserAccount();
    } else {
      return RikiLoginGlobal.isLoginStaffAccount();
    }
  }

  /// 重新启动APP 自动登陆
  Future<bool> autoLogin() async {
    if (!getLoginStatus()) {
      return false;
    }
    if (appType == AppType.user) {
      // user 国美登陆自动登陆更新scn
      return await userAutoLogin();
    } else if (appType == AppType.staff) {
      // staff 通过接口验证当前token是否过期 然后进入App
      return await _userLoginRecord();
    }
    return true;
  }


  /// 更新用户信息
  Future<bool> oauthInfo() async {
    if (appType == AppType.user) {
      return await getUserPersonalInfo();
    } else {
      return await getStaffPersonalInfo();
    }
  }

  /// User 更新用户信息
  void refreshUserLoginEntity(UserLoginEntity entity,{bool? init}) {
    this._userLoginEntity = entity;
    if (init != null && !init) {
      RikiLoginGlobal.saveUserAccount(entity);
    }
  }

  /// staff更新用户信息
  void refreshStaffLoginEntity(StaffLoginEntity entity,{bool? init}) {
    this._staffLoginEntity = entity;
    if (init != null && !init) {
      RikiLoginGlobal.saveStaffAccount(entity);
    }
  }


  /// 更新协议的勾选
  void refreshAgreeAgreement(bool agree){
    this._isAgreement = agree;
    if (appType == AppType.user) {
      RikiLoginGlobal.setUserAgreeAgreement(agree);
    } else {
      RikiLoginGlobal.setStaffAgreeAgreement(agree);
    }
  }



  // ——————————————————————————————————————————

  /// 告诉后台登录成功
  Future userLoginRecord() async {
    UserLoginRecordApi _userLoginRecordApi = UserLoginRecordApi(context);
    _userLoginRecordApi.start(params: {}).then((res) {});
  }


  /// User 登陆
  Future<bool> oauthGomeLogin(String token) async {
    Completer<bool> completer = Completer();
    OauthGomeLoginApi oauthGomeLoginApi = OauthGomeLoginApi(context);

    String idfa = DeviceInfoHelper().idfa;
    String androidImei = await DeviceInfoHelper().getAndroidImei();
    String androidId = await DeviceInfoHelper().getAndroidId();
    String androidOAID = await DeviceInfoHelper().getAndroidIOAID();
    oauthGomeLoginApi
        .start(
            params: oauthGomeLoginApi.params(
      token,
      idfa: idfa,
      imei: androidImei,
      androidId: androidId,
      oaid: androidOAID,
    ))
        .then((res) {
      if (res.success!) {
        // 国美token
        if (res.result == null) {
          ToastUtil.showNegativeToast('登录失败');
          completer.complete(false);
        } else {
          UserLoginEntity entity = res.result!;
          entity.accessToken = token;
          RikiBase.setAccessToken(token);

          RikiLoginGlobal.saveUserAccount(entity);
          this._userLoginEntity = entity;
          userLoginRecord();
          completer.complete(true);
        }

        // Future.delayed(const Duration(seconds: 1), () {
        //   Application.instance.start();
        //   completer.complete();
        // });

      } else {
        if (res.statusCode == 3602) {
          _onLoginDateCallback(context);
        } else {
          ToastUtil.showNegativeToast(res.message);
        }
        completer.complete(false);
      }
    });
    return completer.future;
  }

  /// user 更新用户信息
  Future<bool> getUserPersonalInfo() async {
    final Completer<bool> completer = Completer();
    OauthGomeInfoApi _oauthUserApi = OauthGomeInfoApi(context);
    _oauthUserApi.start(params: {}).then((res) {
      if (res.success ?? false) {
        if (res.result != null) {
          UserLoginEntity loginEntity = res.result!;
          loginEntity.accessToken = RikiLogin.instance.userLoginEntity.accessToken;
          this._userLoginEntity = loginEntity;
          RikiLoginGlobal.saveUserAccount(loginEntity);
          completer.complete(true);
        } else {
          completer.complete(false);
        }
      } else {
        completer.complete(false);
        ToastUtil.showNegativeToast(res.message);
      }
    });
    return completer.future;
  }

  /// staff 获取我的个人资料信息
  Future<bool> getStaffPersonalInfo() async {
    final Completer<bool> completer = Completer();
    OauthUserApi oauthUserApi = OauthUserApi(context);
    oauthUserApi.start(params: {
      'userId': RikiLoginGlobal.getLocalStaffAccount()?.id,
    }).then((res) {
      if (res.success ?? false) {
        if (res.result == null) {
          completer.complete(false);
        } else {
          StaffLoginEntity entity = res.result!;
          entity.accessToken = RikiLogin.instance.userLoginEntity.accessToken;
          this._staffLoginEntity = entity;
          RikiLoginGlobal.saveStaffAccount(entity);
          completer.complete(true);
        }
      } else {
        completer.complete(false);
        ToastUtil.show(res.message);
      }
    });
    return completer.future;
  }

  /// user 国美登陆自动登陆更新scn
  /// 是否需要调用接口验证当前token是否过期（因 杀死APP之后重新进入页面之后IM登陆会顶掉已登录的设备）
  Future<bool> userAutoLogin() async {
    bool gmAutoLogin = await loginManager.autoLogin();
    if (!gmAutoLogin) return false;
    GMMLoginInfo info = await loginManager.getLoginInfo();
    if (info == null) return false;
    this._userLoginEntity.accessToken = info.scn;
    return true;
  }

  /// staff 验证当前是否是登陆状态
  Future<bool> _userLoginRecord() async {
    final Completer<bool> completer = Completer();
    CheckLoginStatusApi checkLoginStatusApi = CheckLoginStatusApi(context);
    checkLoginStatusApi.start(params: {}).then((res) {
      if (res.success ?? false) {
        // 验证通过
        completer.complete(true);
      } else {
        completer.complete(false);
      }
    });
    return completer.future;
  }
}
